import { http } from '@/server'
import { useEffect, useState, useCallback } from 'react'
import type { HttpResponseData } from '@/server/interface'

type RequestParams = {
    per_page: number
} & Record<string, any>

type ResponseBody<T extends any> = {
    total: number
    list: T[]
}

interface Props {
    params?: RequestParams
}

/**
 * 配合InfiniteScroll列表的分页数据请求Hook
 * https://mobile.ant.design/zh/components/infinite-scroll
 * @param url 请求URL
 * @param props 参数
 * @returns
 */
export const useFetchPageList = <T extends any>(url: string, props?: Props) => {
    /** 初始页码 */
    const START_PAGE = 1

    /** 初始请求参数 */
    const BASE_PARAMS: RequestParams = props?.params ?? { per_page: 10 }

    /** 当前页数 */
    const [currentPage, setCurrentPage] = useState<number>(START_PAGE)

    /** 基础请求参数 */
    const [baseParams] = useState<RequestParams>(BASE_PARAMS)

    /** 筛选请求参数 */
    const [filterParams, setFilterParams] = useState<Record<string, any>>({})

    /** 是否有未加载完的数据 */
    const [hasMore, setHasMore] = useState<boolean>(false)

    /** 数据是否加载中 */
    const [loading, setLoading] = useState<boolean>(false)

    /** 数据列表 */
    const [dataList, setDataList] = useState<T[]>([])

    /** 基础请求 */
    const baseRequest = useCallback(
        async (params: RequestParams): Promise<HttpResponseData<ResponseBody<T>>> =>
            http.get(`${url}`, { params: { ...params } }),
        [url],
    )

    const fetchList = useCallback(
        async (page: number) => {
            try {
                setLoading(true)

                const { data } = await baseRequest({
                    ...baseParams,
                    ...filterParams,
                    page,
                })

                const { total = 0, list = [] } = data

                setDataList(oldList => {
                    const newList = [...oldList, ...list]

                    setHasMore(newList.length < total)

                    return newList
                })
            } catch (error) {
                console.error('🐞 => fetchList => error', error)
            } finally {
                setLoading(false)
            }
        },
        [baseParams, filterParams, baseRequest],
    )

    useEffect(() => {
        fetchList(START_PAGE)
    }, [fetchList])

    /**
     * InfiniteScroll 会自动对 loadMore 函数加锁，避免重复的请求，
     * 但是前提是 loadMore 函数需要返回一个正确的 Promise
     */
    const loadMore = async () => {
        if (!hasMore) return

        const nextPage = currentPage + 1

        setCurrentPage(nextPage)

        await fetchList(nextPage)
    }

    /** 刷新列表数据 */
    const refreshList = async () => {
        const { data } = await baseRequest({
            ...baseParams,
            ...filterParams,
            page: START_PAGE,
            per_page: dataList.length,
        })

        const { list = [] } = data

        setDataList(list)
    }

    /** 更新筛选项值 */
    const updateFilterParams = (params: Record<string, any>) => {
        // 筛选参数未发生变化
        if (JSON.stringify(filterParams) === JSON.stringify(params)) return

        // 更新参数并重置页面数据
        setDataList([])
        setFilterParams(params)
        setCurrentPage(START_PAGE)
    }

    return { dataList, hasMore, loading, loadMore, refreshList, updateFilterParams } as const
}
